// window.onerror = function(errorMessage, scriptURI, lineNumber, columnNumber, errorObj) {
//      window.alert("错误" + errorMessage + " 脚本" +  scriptURI + " 位置" + lineNumber + ":" + columnNumber
//      + " 对象" + errorObj)
//      return false;
// }

window.__onNativeCall = function(args) {
     if (!window.__native) {
          return;
     }
     window.__native.__onNativeCall(args.name, args.id, args.isRemoveCallback, args.error, args.data)
}

import {Task} from "./task.js"

/**
 * 底层接口，应用层请勿直接调用，以免打乱运行环境
 * @version 2
 * @author GuoHua Liu
 * @copyright Copyright © 2019 GuoHua Liu. All rights reserved.
 */
class Native {

     constructor() {
          this.__observerss = {} // 事件观察
          this.__waitCallbacks = {}
          this.__id = 1
     }

     /**
      * 获取该类的单例
      * @returns {Native}
      */
     static getInstance() {
          if(window.__native) {
               return window.__native
          }
          window.__native = new Native()
          return window.__native
     }

     isHos() {
          if(this.isIOS()) {
              return true
          }
          if(this.isAndroid()) {
              return true
          }
          return false
      }

     isIOS() {
          if (window.hasOwnProperty("webkit")
              && (typeof window.webkit.messageHandlers)
              && (typeof window.webkit.messageHandlers.toast)
          ) {
              return true
          }
          return false
      }

      isAndroid() {
          return window.__HosBridge? true:false;
      }

     __addRequest (request) {
            while(true) {
               if(this.__id > 65536) {
                    this.__id = 1
               }
               if (this.__waitCallbacks[this.__id += 1]) {
                    continue
               }
               break
            }

            this.__waitCallbacks[this.__id] = request
            request.__id =  this.__id
            return request.__id
     }

     __delRequest (task) {
          // console.log("删除任务:" + task.__id)
          if (this.__waitCallbacks[task.__id]) {
               this.__waitCallbacks[task.__id] = undefined
               task.__id = 0 //
               return
          }
          // console.warn("尝试删除任务,但是该任务不存-->" + task.__id)
     }


     __onNativeCall(name, id, isRemoveCallback, error, data) {

            // 事件

            if (id < 0) {
                this.__fireEvent(name, id, data)
            }

            // 普通任务

            let task = this.__waitCallbacks[id]

            if (task) {
               // console.log("任务处理结束-->" + task.__id + "," + id)
               if (!error) {
                    // console.log("解决任务-->" + task.__id + "," + task.name)
                    task.__resolve(data)//
                 } else {
                    // console.log("失败任务-->" + task.__id + "," + task.name)
                    task.__reject(data)
                 }

                 if (isRemoveCallback) {
                    this.__delRequest(task)
                 }
            }
       }


       exec(cmd) {
          let path = "cmd/" + cmd
          let xhr = new XMLHttpRequest()
          xhr.open('get', path, false)
          xhr.send(null)
          return xhr.responseText
      }


    /**
     *
     * @param name
     * @param data
     * @return {object}
     */
      syncCallNative (name, data) {
           let res = prompt(name, JSON.stringify(data))
           return JSON.parse(res)
      }

      /**
       * 添加观察者
       * @param {String} name 插件名称
       * @param {*} context onevent函数所在的上下文
       * @param {Function} onevent 观察者函数
       */
     addObserver(name, context, onevent) {

          if (typeof onevent != "function") {
               let ctx = onevent
               onevent = context
               context = ctx
          }

          if (typeof onevent != "function") {
               console.error("参数错误")
          }

          let observer = {"onevent":onevent, "context":context};

          let observers = this.__observerss[name]
          if (!observers) {
               observers = this.__observerss[name] = [observer]
          } else {
               this.delObserver(name, onevent) // 避免多次添加
               observers.push(observer)
          }
          // console.log("addObserver-->" + name + "," + observers.length, onevent, observer)
     }

     /**
      * 发射事件
      * @param {String} name
      * @param {Number} id
      * @param {Object} data
      */
     __fireEvent(name, id, data) {
          // console.log("发射事件", name, id, data)
          let observers = this.__observerss[name]
          if (observers) {
               (function () {
                    let i = observers.length
                    while(i--){
                         let observer = observers[i]
                         if(!observer || !observer.onevent){
                              // console.log("清理无效观察者", observer, observers.length)
                              observers.splice(i,1)
                         }
                    }
               })()

               for (let index in observers) {
                    let observer = observers[index]
                    // console.log("观察者", observer, "执行函数", observer.onevent, "上下文", observer.context)
                    if (observer.context) {
                         // 用户指定了执行上下文
                         observer.onevent.call(observer.context, {"name":name, "id":id, "data":data})
                    } else {
                         observer.onevent({"name":name, "id":id, "data":data})
                    }
               }
          }
     }

     /**
      * 删除观察者
      * @param {String} name 插件名称
      * @param {*} onevent 观察者函数
      */
     delObserver(name, onevent=null) {
          let observers = this.__observerss[name];
          if (!observers) {
               // console.warn("尝试移除" + name + "的一个观察者,但是它不存在")
               return
          } else {
              // >> 删除所有观察者 since 2
               if(!onevent) {
                   this.__observerss[name] = [];
                   console.log("delObserver-->remove all observer");
                   return
               }
               // <<
              for(let index in observers) {
                  if (observers.hasOwnProperty(index)) {
                      const observer = observers[index];
                      if(observer.onevent === onevent) {
                          observer.onevent = undefined;
                          observer.context = undefined;
                          observers.splice(index, 1);
                          break
                      }
                  }
              }
          }
          // console.log("delObserver-->" + name + "," + observers.length)
     }

     /**
      * 调用底层异步执行任务
      * @param {String} name 插件名称
      * @param {Object} data  发送的数据
      * @param {boolean} isWaitCallBack 是否要求回调
      * @param {function} onsuccess 成功回调函数
      * @param {function} onfail 失败回调函数
      * @returns {Task}
      */
     callNative (name, data, isWaitCallBack = false, onsuccess = undefined, onfail = undefined) {

           if (isWaitCallBack) {
               let task = new Task()
               task.__user_resolove = onsuccess
               task.__user_reject = onfail
               task.name = name
               let id = this.__addRequest(task)
               // console.log("提交新任务-->" + task.__id + "," + task.name)//

               if (this.isIOS()) {
                    window.webkit.messageHandlers.__onJsCall.postMessage(
                         {name:name,
                         id:id,
                         data:data})
                } else if (this.isAndroid()) {
                    window.__HosBridge.__onJsCall(JSON.stringify(
                         {name:name,
                         id:id,
                         data:data}))
                }

                task.__setAbort(()=>{
                    // console.log("打断任务-->" + task.__id + "," + task.name)//
                    if (task.__id != 0) {
                         this.__delRequest(task)
                    }
                })
               //  console.log("任务已经完成提交-->" + task.__id + "," + task.name)//
                return task
           } else {
               if (this.isIOS()) {
                    window.webkit.messageHandlers.__onJsCall.postMessage(
                         {name:name,
                         id:0, // 此时id无用
                         data:data})
                    return
                } else if (this.isAndroid()) {
                   window.__HosBridge.__onJsCall(JSON.stringify(
                        {name:name,
                        id:0, // 此时id无用
                        data:data}))
                    return
               }
           }
           // alert("环境不支持" + name)
       }
}


export {Native}
